Skip to content

Scope OG rendering assets to each request - #1087

Merged
tannerlinsley merged 1 commit into
mainfrom
agent/scope-og-render-assets
Jul 31, 2026
Merged

Scope OG rendering assets to each request#1087
tannerlinsley merged 1 commit into
mainfrom
agent/scope-og-render-assets

Conversation

@tannerlinsley

@tannerlinsley tannerlinsley commented Jul 31, 2026

Copy link
Copy Markdown
Member

Evidence\n\nPR #1076 expanded the shared cold render path from three static assets to five and registered the logo plus both emblems on every request, although each rendered image uses exactly one of them.\n\n## Impact\n\n- Standard /api/og requests stop fetching and registering two unused emblems: two fewer asset-binding reads and 17,685 fewer bytes.\n- README header requests load only the emblem for the requested theme, avoiding the unused logo and opposite-theme emblem: one fewer registration and roughly 18 KB less asset data.\n- Fonts and the selected image load concurrently and remain cached independently.\n\nThe generated image contract and cache headers are unchanged.\n\n## Validation\n\n- pnpm test: TypeScript, type-aware lint, and 140 tests (139 passed, 1 skipped)\n- Full scripts/og-preview.ts render set\n- Full pnpm run readme:preview render set\n- git diff --check\n\n## Risk\n\nLow. The change only scopes the existing asset loader and ImageResponse registrations; both render paths completed their full preview matrices.

Summary by CodeRabbit

  • Improvements

    • Updated Open Graph image generation to load only the branding assets needed for each image.
    • Improved support for theme-specific branding in README header images.
    • Added more efficient asset loading and caching, reducing unnecessary image requests and processing.
  • Bug Fixes

    • Improved fallback handling when branding assets are loaded from local files or request URLs.

@tannerlinsley tannerlinsley added the source-audit Tracked by the automated source audit label Jul 31, 2026
@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

OG asset loading now uses keyed image assets with separate font and image caches. Standard OG and README header generators preload the required assets and pass them to renderOgImage.

Changes

OG asset loading and rendering

Layer / File(s) Summary
Asset registry and keyed cache
src/server/og/assets.server.ts
Defines keyed logo and emblem assets. Separately caches fonts and selected images. Uses local files first, then request-URL fallback loading.
Preloaded rendering contract
src/server/og/generate.server.ts
renderOgImage accepts preloaded fonts and image mappings instead of loading assets from a request URL.
OG generator asset wiring
src/server/og/generate.server.ts
Standard OG generation loads the logo. README header generation loads the emblem for the selected theme and passes it to rendering.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant StandardOG as Standard OG generator
  participant READMEHeader as README header generator
  participant loadOgAssets
  participant renderOgImage
  StandardOG->>loadOgAssets: load logo asset and fonts
  loadOgAssets-->>StandardOG: return fonts and logo image data
  StandardOG->>renderOgImage: render with preloaded assets
  READMEHeader->>loadOgAssets: load theme emblem and fonts
  loadOgAssets-->>READMEHeader: return fonts and theme emblem data
  READMEHeader->>renderOgImage: render with preloaded assets
Loading

Possibly related PRs

Suggested reviewers: alemtuzlak

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: scoping OG rendering assets to each request.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent/scope-og-render-assets

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
tanstack-com 3b83397 Commit Preview URL

Branch Preview URL
Jul 31 2026, 09:15 PM

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/server/og/assets.server.ts (1)

68-97: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Use single-flight caches for cold requests.

cachedFonts and cachedImages are populated only after loading completes. Concurrent cold requests can each start duplicate font and image loads. Cache the pending Promise values, and remove a rejected promise so later requests can retry.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/server/og/assets.server.ts` around lines 68 - 97, Update loadFonts and
loadOgAssets to cache in-flight Promise values rather than only completed
results, so concurrent cold requests share one font or image load. Store the
pending promise before awaiting it, and remove the corresponding cachedFonts or
cachedImages entry when loading rejects so subsequent requests can retry;
preserve the existing resolved return values and asset mapping.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/server/og/assets.server.ts`:
- Around line 68-97: Update loadFonts and loadOgAssets to cache in-flight
Promise values rather than only completed results, so concurrent cold requests
share one font or image load. Store the pending promise before awaiting it, and
remove the corresponding cachedFonts or cachedImages entry when loading rejects
so subsequent requests can retry; preserve the existing resolved return values
and asset mapping.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 263d6b8c-b421-45de-a29d-cf063e233ca4

📥 Commits

Reviewing files that changed from the base of the PR and between fd29784 and 3b83397.

📒 Files selected for processing (2)
  • src/server/og/assets.server.ts
  • src/server/og/generate.server.ts

@tannerlinsley
tannerlinsley merged commit 14ef1d4 into main Jul 31, 2026
7 checks passed
@tannerlinsley
tannerlinsley deleted the agent/scope-og-render-assets branch July 31, 2026 21:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

source-audit Tracked by the automated source audit

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant